// Copyright 2022 a.o.smith ALL Rights Reserved
package com.liuxinlong.modules.material.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.liuxinlong.api.WeChatMessageInterface;
import com.liuxinlong.common.AosException;
import com.liuxinlong.common.SnowFlake;
import com.liuxinlong.constant.TimeFormatConstants;
import com.liuxinlong.enums.ConvolutionStatusTypeEnum;
import com.liuxinlong.enums.MessageContentTypeEnum;
import com.liuxinlong.enums.MessagePushBusinessEnum;
import com.liuxinlong.enums.NotificationSourceEnum;
import com.liuxinlong.enums.ReturnCodes;
import com.liuxinlong.modules.dao.MaterialConvolutionDao;
import com.liuxinlong.modules.dao.MaterialConvolutionLogDao;
import com.liuxinlong.modules.dao.MaterialRollupDao;
import com.liuxinlong.modules.dao.MaterialRollupResultDao;
import com.liuxinlong.modules.dao.NotificationDao;
import com.liuxinlong.modules.dao.ParameterDao;
import com.liuxinlong.modules.dao.UserDao;
import com.liuxinlong.modules.entity.MaterialConvolution;
import com.liuxinlong.modules.entity.MaterialConvolutionLog;
import com.liuxinlong.modules.entity.MaterialRollup;
import com.liuxinlong.modules.entity.MaterialRollupResult;
import com.liuxinlong.modules.entity.MessageConfiguration;
import com.liuxinlong.modules.entity.Notification;
import com.liuxinlong.modules.material.service.MaterialRollupService;
import com.liuxinlong.push.MessagePushService;
import com.liuxinlong.utils.ObjectUtils;
import com.liuxinlong.utils.TimeUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 物料滚价service实现
 *
 * @author liuxinlong@hotwater.com.cn
 * @version 1.0.0
 * @since 2023年6月1日
 */
@Service
@Slf4j
public class MaterialRollupServiceImpl implements MaterialRollupService {

    @Autowired
    private MaterialRollupDao materialRollupDao;

    @Autowired
    private MaterialConvolutionDao materialConvolutionDao;

    @Autowired
    private MaterialRollupResultDao materialRollupResultDao;

    @Autowired
    private MaterialConvolutionLogDao materialConvolutionLogDao;

    @Autowired
    private ParameterDao parameterDao;

    @Autowired
    private NotificationDao notificationDao;

    @Autowired
    private WeChatMessageInterface weChatMessageInterface;

    @Autowired
    private MessagePushService messagePushService;

    @Autowired
    private UserDao userDao;

    @Override
    public List<Map<String, Object>> pageRollupList(Map<String, Object> queryParam) {
        List<MaterialRollup> originalList = materialRollupDao.pageRollupList(queryParam);
        int startNum = (int) queryParam.get("startNum");
        return completeData(originalList, startNum);
    }

    @Override
    public int getRollupCount(Map<String, Object> queryParam) {
        return materialRollupDao.getRollupCount(queryParam);
    }

    @Override
    public void addRollup(MaterialRollup materialRollup) {
        MaterialConvolution convolution = materialConvolutionDao.selectById(materialRollup.getConvolutionId());
        if (ObjectUtils.isEmpty(convolution)) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "物料成本卷积记录不存在！");
        }
        if (convolution.getStatus() == ConvolutionStatusTypeEnum.CONVOLUTION_PROGRESSING.getValue() || convolution.getStatus() == ConvolutionStatusTypeEnum.STATUS_CHANGING.getValue() || convolution.getStatus() == ConvolutionStatusTypeEnum.STATUS_FINISHED.getValue()) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "当前状态不能进行卷积！");
        }
        materialRollup.setId(SnowFlake.nextIdStr());
        materialRollupDao.insert(materialRollup);
    }

    @Override
    public void updateRollup(MaterialRollup materialRollup) {
        MaterialConvolution convolution = materialConvolutionDao.selectById(materialRollup.getConvolutionId());
        if (ObjectUtils.isEmpty(convolution)) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "物料成本卷积记录不存在！");
        }
        materialRollupDao.updateById(materialRollup);
    }

    @Override
    @Transactional
    public void updateRollupOut(String id, String result, String content) {
        MaterialRollup materialRollup = materialRollupDao.selectById(id);
        if (ObjectUtils.isEmpty(materialRollup)) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "物料滚价记录不存在！");
        }
        if (materialRollup.getStatus() != 0) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "物料滚价结果已更新，不可重复更新！");
        }
        materialRollup.setContent(content);
        String currentTime = TimeUtils.getDate(TimeFormatConstants.YYYY_MM_DD_HH_MM_SS);
        Map<String, Object> contentMap = (Map<String, Object>) JSON.parse(content);
        List<Map<String, Object>> dataList = (List<Map<String, Object>>) contentMap.get("rtnbody");
        List<MaterialRollupResult> resultList = new ArrayList<>();
        boolean checkFlag = true;
        boolean oneFlag = false;
        boolean twoFlag = false;
        for (Map<String, Object> item : dataList) {
            MaterialRollupResult materialRollupResult = new MaterialRollupResult();
            materialRollupResult.setId(SnowFlake.nextIdStr());
            materialRollupResult.setRollupId(id);
            materialRollupResult.setErrorType((int) item.get("errornum"));
            if ((int) item.get("errornum") == 4) {
                checkFlag = false;
            }
            if ((int) item.get("errornum") == 1) {
                oneFlag = true;
            }
            if ((int) item.get("errornum") == 2) {
                twoFlag = true;
            }
            materialRollupResult.setCreateTime(currentTime);
            List<Map<String, Object>> errorList = (List<Map<String, Object>>) JSON.parse(JSONObject.toJSONString(item.get("errorbody")));
            List<String> contentList = new ArrayList();
            for (Map<String, Object> errorContent : errorList) {
                contentList.add((String) errorContent.get("compitem"));
            }
            if (!ObjectUtils.isEmpty(contentList)) {
                materialRollupResult.setErrorContent(StringUtils.deleteWhitespace(StringUtils.strip(contentList.toString(), "[]")));
            }
            resultList.add(materialRollupResult);
        }
        MaterialConvolution materialConvolution = materialConvolutionDao.selectById(materialRollup.getConvolutionId());
        if (!ObjectUtils.isEmpty(resultList)) {
            materialRollupResultDao.insertBatch(resultList);
        }
        materialRollup.setStatus(1);
        materialRollup.setUpdateTime(currentTime);
        materialRollupDao.updateById(materialRollup);
        materialConvolution.setStatus(ConvolutionStatusTypeEnum.CONVOLUTION_FINISHED.getValue());
        materialConvolution.setCheckable(checkFlag && !(oneFlag && twoFlag) ? 1 : 2);
        materialConvolutionDao.updateById(materialConvolution);
        pushMessage(materialConvolution, materialConvolution.getCreateUser(), currentTime);
        MaterialConvolutionLog materialConvolutionLog = materialConvolutionLogDao.getLogByRecordId(id);
        if (ObjectUtils.isEmpty(materialConvolutionLog)) {
            int currentSort = materialConvolutionLogDao.getCurrentSort(materialRollup.getConvolutionId());
            MaterialConvolutionLog logInfo = new MaterialConvolutionLog();
            logInfo.setId(SnowFlake.nextIdStr());
            logInfo.setConvolutionId(materialRollup.getConvolutionId());
            logInfo.setRecordId(id);
            logInfo.setSerial(currentSort + 1);
            logInfo.setNode(2);
            logInfo.setCreateTime(currentTime);
            materialConvolutionLogDao.insert(logInfo);
            return;
        }
        materialConvolutionLog.setStatus(1);
        materialConvolutionLog.setCreateTime(currentTime);
        materialConvolutionLogDao.updateById(materialConvolutionLog);
    }

    @Override
    public void deleteRollup(String id) {

    }

    /**
     * 补全数据
     *
     * @param originalList 原数据
     * @param startNum     起始数据
     * @return 补全后数据
     */
    private List<Map<String, Object>> completeData(List<MaterialRollup> originalList, int startNum) {
        List<Map<String, Object>> dataList = new ArrayList<>(originalList.size());
        int sort = startNum + 1;
        for (MaterialRollup materialRollup : originalList) {
            Map<String, Object> item = ObjectUtils.object2Map(materialRollup);
            item.put("sort", sort);
            dataList.add(item);
            sort++;
        }
        return dataList;
    }

    /**
     * 物料卷积消息推送
     *
     * @param materialConvolution 物料卷积记录
     * @param operateUser         当前操作人
     * @param currentTime         当前时间
     */
    private void pushMessage(MaterialConvolution materialConvolution, String operateUser, String currentTime) {
        Map<String, Map<String, String>> userMap = userDao.getUserMap();
        List<Notification> notificationList = new ArrayList<>();
        int status = materialConvolution.getStatus();
        String region = materialConvolution.getRegion();
        String content = "物料【" + materialConvolution.getMaterialNo() + " | " + materialConvolution.getMaterialName() + "】 在域【" + region + "】" + ConvolutionStatusTypeEnum.getNameByValue(status);
        List<String> targetList = new ArrayList<>();
        targetList.add(operateUser);
        targetList.addAll(Arrays.asList(materialConvolution.getCopyUser().split(",")));
        List<String> targetUserList = targetList.stream().distinct().collect(Collectors.toList());
        for (String tar : targetUserList) {
            if (!userMap.containsKey(tar)) {
                continue;
            }
            Notification notification = new Notification();
            notification.setId(SnowFlake.nextIdStr());
            notification.setCreateTime(currentTime);
            notification.setCreateUser(operateUser);
            notification.setSourceId(materialConvolution.getId());
            notification.setContent(content);
            notification.setDealUser(tar);
            notification.setSourceType(NotificationSourceEnum.CONVOLUTION_MODULE.getValue());
            notificationList.add(notification);
            Map<String, String> contentMap = new HashMap<>();
            contentMap.put("title", "您有一条新消息待查看");
            contentMap.put("description", notification.getContent());
            String contentStr = JSON.toJSONString(contentMap);
            Map<String, String> targetUser = userMap.get(tar);
            messagePushService.pushMessage(contentStr, targetUser.get("sn"));
        }
        notificationDao.insertBatch(notificationList);
        MessageConfiguration messageConfiguration = new MessageConfiguration();
        messageConfiguration.setBusinessType(MessagePushBusinessEnum.CONVOLUTION.getValue());
        messageConfiguration.setContent(content);
        messageConfiguration.setContentType(MessageContentTypeEnum.TEXT_CARD.getValue());
        weChatMessageInterface.pushMessage(targetUserList, null, messageConfiguration, currentTime);

    }
}
